package com.hy.study.linkedlist;

/**
 * 双向链表类
 */
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        System.out.println("双向链表的测试");
        HeroNode sj = new HeroNode(1, "宋江", "及时雨");
        HeroNode ljy = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode wuyong = new HeroNode(3, "吴用", "智多星");
        HeroNode linchong = new HeroNode(4, "林冲", "豹子头");


        DoubleLinkedList doubleLinkedList=new DoubleLinkedList();
        doubleLinkedList.addLast(sj);
        doubleLinkedList.addLast(ljy);
        doubleLinkedList.addLast(wuyong);
        doubleLinkedList.addLast(linchong);

        doubleLinkedList.list();
        System.out.println("---------------修改之后的-------------");
        HeroNode linchong2 = new HeroNode(4, "公孙胜", "入云龙");
        doubleLinkedList.update(linchong2);
        doubleLinkedList.list();
        System.out.println("--------------删掉之后的-------------");
        doubleLinkedList.delete(3);
        doubleLinkedList.list();


        System.out.println("----------排序添加之后----------");

        DoubleLinkedList doubleLinkedListOrderby=new DoubleLinkedList();
        HeroNode sjOrderBy = new HeroNode(1, "宋江", "及时雨");
        HeroNode ljyOrderBy = new HeroNode(5, "卢俊义", "玉麒麟");
        HeroNode wuyongOrderBy = new HeroNode(8, "吴用", "智多星");
        HeroNode linchongOrderBy = new HeroNode(4, "林冲", "豹子头");
        doubleLinkedListOrderby.addOrderByNo(sjOrderBy);
        doubleLinkedListOrderby.addOrderByNo(ljyOrderBy);
        doubleLinkedListOrderby.addOrderByNo(wuyongOrderBy);
        doubleLinkedListOrderby.addOrderByNo(linchongOrderBy);
        doubleLinkedListOrderby.list();

    }
}

class DoubleLinkedList {
    private HeroNode head = new HeroNode();

    public HeroNode getHead() {
        return head;
    }

    /**
     * 从双向链表中删除一个节点
     *
     * @param no
     */
    public void delete(int no) {
        if (head.getNext() == null) {
            System.out.println("链表为空无法删除");
            return;
        }
        boolean flag = false;
        HeroNode temp = head.getNext();
        while (temp != null) {
            if (temp.getNo() == no) {
                flag = true;
                break;
            }
            temp = temp.getNext();
        }
        //删除节点 改变双向指针
        if (flag) {
            temp.getPre().setNext(temp.getNext());
            //这里有坑 如果删除的是最后一个节点 会报空指针
            if(temp.getNext()!=null){
                temp.getNext().setPre(temp.getPre());
            }
        }else {
            System.out.println("需要删除的"+no+"节点不存在");
        }

    }

    /**
     * 修改双向链表的值
     *
     * @param node
     */
    public void update(HeroNode node) {
        if (head.getNext() == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head.getNext();
        boolean flag = false;
        while (temp != null) {
            if (temp.getNo() == node.getNo()) {
                flag = true;
                break;
            }
            temp = temp.getNext();
        }
        if (flag) {
            temp.setName(node.getName());
            temp.setNickName(node.getNickName());
        }

    }

    /**
     * 添加到双向链表的后面
     *
     * @param node
     */
    public void addLast(HeroNode node) {
        HeroNode temp = head;
        while (true) {
            if (temp.getNext() == null) {
                //找到了
                break;
            }
            temp = temp.getNext();
        }
        //形成一个双向链表
        temp.setNext(node);
        node.setPre(temp);

    }

    /**
     * 按照编号顺序添加
     * @param node
     */
    public void addOrderByNo(HeroNode node){
        HeroNode temp=head;
        boolean flag=false;

        while (true){
            if(temp.getNext()==null){
                flag=true;
                break;
            }
            if(temp.getNext().getNo()>node.getNo()){
                flag=true;
                break;
            }else  if(temp.getNext().getNo()==node.getNo()){
                System.out.println("已经存在相同的数据 无法添加");
                break;
            }
            temp=temp.getNext();
        }
        if(flag){
            node.setNext(temp.getNext());
            if(temp.getNext()!=null){
                node.setPre(temp.getNext().getPre());
                temp.getNext().setPre(node);
            }
            temp.setNext(node);
        }else {
            System.out.println("没有知道添加的位置");
        }

    }


    /**
     * 遍历双向链表的方法
     */
    public void list() {
        if (head.getNext() == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head.getNext();
        while (temp != null) {
            System.out.println(temp);
            temp = temp.getNext();
        }

    }
}

class HeroNode {

    private int no;
    private String name;
    private String nickName;
    private HeroNode next;//指向下一个节点
    private HeroNode pre;//指向上一个节点

    public HeroNode() {
    }

    public HeroNode(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public HeroNode getNext() {
        return next;
    }

    public void setNext(HeroNode next) {
        this.next = next;
    }

    public HeroNode getPre() {
        return pre;
    }

    public void setPre(HeroNode pre) {
        this.pre = pre;
    }
}